#include "DotView.h"
#include <QPainter>
#include "../Controllers/DotController.h"
#include "../DrawingElements/Dot.h"
#include "../Models/DotModel.h"
#include "../DataStructure/OneD2TwoD.h"
#include "../Settings/GameSettings.h"
#include <QInputDialog>
#include <QAbstractTextDocumentLayout>
#include <QTextDocument>
#include <QFile>
#include "StatusViewer.h"

DotView::DotView(QWidget *parent) :
    QWidget(parent),mpController(0),mpDocDesc(NULL), mbDrawHowToPlay(false), mbDrawCommands(false)
{    
    setAttribute(Qt::WA_AcceptTouchEvents);
    connect(GameSettings::me(),SIGNAL(settingChanged()),SLOT(update()));
    loadDescription(":res/res/htp.html");
    loadCommandsDesc(":res/res/commnads.html");
}


void DotView::addListener(DotController *pController)
{
    mpController = pController;
    connect(mpController,SIGNAL(gameStarted()),SLOT(update()));
}

void DotView::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    painter.begin(this);

    if(mpController && (mpController->isGameRunning() || mpController->isGameFinished())  && mpController->model()){
        painter.setRenderHint(QPainter::Antialiasing);
        drawBG(&painter);
        drawLines(&painter);
        drawDots(&painter);        
        drawCellOwnership(&painter);
        mpController->draw(&painter);
    }

    if(mbDrawHowToPlay){
        paintDescription(&painter,mpDocDesc);
    }

    if(mbDrawCommands){
        paintDescription(&painter,mpDocCommands);
    }

    painter.end();
}

void DotView::drawDots(QPainter *pDC)
{
    OneD2TwoD<Dot*> *pDots = mpController->model()->dots();
    unsigned int nDotCount = pDots->count();

    for(unsigned int i = 1; i <= nDotCount; i++){
        pDots->get(i)->draw(pDC);
    }
}

void DotView::drawBG(QPainter *pDC)
{
    pDC->setBrush(GameSettings::me()->brush(Game::BGColor));
    pDC->drawRect(rect());

    pDC->setBrush(GameSettings::me()->brush(Game::FieldColor));
    int nShift = GameSettings::me()->setting(Game::DotRadii).value<uint>() + 0;
    pDC->drawRect(mpController->model()->fieldRect().adjusted(-nShift,-nShift,nShift,nShift));
}

void DotView::drawLines(QPainter *pDC)
{
    QList<Line*> *pLines = mpController->model()->lines();
    unsigned int nLineCount = pLines->count();

    for(unsigned int i = 0; i < nLineCount; i++){
        pLines->at(i)->draw(pDC);
    }
}

void DotView::drawCellOwnership(QPainter *pDC)
{
    OneD2TwoD<Cell*> *pCells = mpController->model()->cells();
    unsigned int nCellCount = pCells->count();

    for(unsigned int i = 1; i <= nCellCount; i++){
        pCells->get(i)->drawOwner(pDC);
    }
}

void DotView::mousePressEvent(QMouseEvent *pEvent)
{
    if(mbDrawHowToPlay){
        setHowToPlayEnabled(false);
        return;
    }

    if(mbDrawCommands){
        setShowCommandsEnabled(false);
        return;
    }

    if(mpController->isGameRunning()){
        mpController->mousePressEvent(pEvent);
    }

    QWidget::mousePressEvent(pEvent);
}

void DotView::needToResized(int nWidth, int nHeight)
{
    uint nMargin = GameSettings::me()->setting(Game::FieldMargin).value<uint>();
    resize(nWidth + 2 * nMargin, nHeight + 2 * nMargin);
}

void DotView::showHowToPlay()
{
    setHowToPlayEnabled(true);
}

void DotView::setHowToPlayEnabled(bool bEnable)
{
    StatusViewer::me()->showTempMsg(bEnable ? "Click on the 'How to Play?' window to disappear it" : "'How to Play?' window diappeared.",bEnable ? 0 : LONG_DURATION);

    if(mbDrawCommands && bEnable){
        setShowCommandsEnabled(false);
    }

    if(mbDrawHowToPlay != bEnable){
        mbDrawHowToPlay = bEnable;
        update();
    }
}

void DotView::showCommands()
{
    setShowCommandsEnabled(true);
}

void DotView::setShowCommandsEnabled(bool bEnable)
{
    StatusViewer::me()->showTempMsg(bEnable ? "Click on the 'Commands Window' window to disappear it" : "'Commands Window' window diappeared.",bEnable ? 0 : LONG_DURATION);

    if(mbDrawHowToPlay && bEnable){
        setHowToPlayEnabled(false);
    }

    if(mbDrawCommands != bEnable){
        mbDrawCommands = bEnable;
        update();
    }
}

void DotView::loadDescription(const QString &fileName)
{
    QFile textFile(fileName);
    QString text;

    if (!textFile.open(QFile::ReadOnly)){
        text = QString("Unable to load resource file: '%1'").arg(fileName);
    }
    else{
        text = textFile.readAll();
    }

    setDescription(text);
}

void DotView::setDescription(const QString &text)
{
    mpDocDesc = new QTextDocument(this);
    mpDocDesc->setHtml(text);
}

void DotView::loadCommandsDesc(const QString &fileName)
{
    QFile textFile(fileName);
    QString text;

    if (!textFile.open(QFile::ReadOnly)){
        text = QString("Unable to load resource file: '%1'").arg(fileName);
    }
    else{
        text = textFile.readAll();
    }

    setCommandsDesc(text);

}

void DotView::setCommandsDesc(const QString &text)
{
    mpDocCommands = new QTextDocument(this);
    mpDocCommands->setHtml(text);
}

void DotView::paintDescription(QPainter *painter,QTextDocument *pTextDoc)
{
    if (!pTextDoc){
        return;
    }

    int pageWidth = qMax(width() - 100, 400);
    int pageHeight = qMax(height() - 100, 300);

    if (pageWidth != pTextDoc->pageSize().width()){
        pTextDoc->setPageSize(QSize(pageWidth, pageHeight));
    }

    QRect textRect(width() / 2 - pageWidth / 2,
                   height() / 2 - pageHeight / 2,
                   pageWidth,
                   pageHeight);
    int pad = 10;
    QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(0, 0, 0, 63));
    int shade = 10;
    painter->drawRect(clearRect.x() + clearRect.width() + 1,
                      clearRect.y() + shade,
                      shade,
                      clearRect.height() + 1);
    painter->drawRect(clearRect.x() + shade,
                      clearRect.y() + clearRect.height() + 1,
                      clearRect.width() - shade + 1,
                      shade);

    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->setBrush(QColor(255, 255, 255, 220));
    painter->setPen(Qt::black);
    painter->drawRect(clearRect);

    painter->setClipRegion(textRect, Qt::IntersectClip);
    painter->translate(textRect.topLeft());

    QAbstractTextDocumentLayout::PaintContext ctx;

    QLinearGradient g(0, 0, 0, textRect.height());
    g.setColorAt(0, Qt::black);
    g.setColorAt(0.9, Qt::black);
    g.setColorAt(1, Qt::transparent);

    QPalette pal = palette();
    pal.setBrush(QPalette::Text, g);

    ctx.palette = pal;
    ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
    pTextDoc->documentLayout()->draw(painter, ctx);
}
